#pragma once

#include <string>
#include <chrono>
#include <unordered_map>
#include <mutex>
#include <deque>
#include <vector>
#include <algorithm>
#include <numeric>
#include <iostream>

namespace hft {

struct LatencyStats {
    double min_latency;      // 最小延迟（微秒）
    double max_latency;      // 最大延迟（微秒）
    double avg_latency;      // 平均延迟（微秒）
    double p95_latency;      // 95分位延迟（微秒）
    double p99_latency;      // 99分位延迟（微秒）
    size_t sample_count;     // 样本数量
};

class PerformanceMonitor {
public:
    static std::shared_ptr<PerformanceMonitor> getInstance() {
        static std::shared_ptr<PerformanceMonitor> instance(new PerformanceMonitor());
        return instance;
    }
    
    // 记录延迟
    void recordLatency(const std::string& stage, double latency_us) {
        std::lock_guard<std::mutex> lock(mutex_);
        auto& samples = latency_samples_[stage];
        samples.push_back(latency_us);
        
        // 保持最近1000个样本
        if (samples.size() > 1000) {
            samples.pop_front();
        }
    }
    
    // 获取延迟统计信息
    LatencyStats getLatencyStats(const std::string& stage) const {
        std::lock_guard<std::mutex> lock(mutex_);
        LatencyStats stats = {0.0, 0.0, 0.0, 0.0, 0.0, 0};
        
        auto it = latency_samples_.find(stage);
        if (it == latency_samples_.end() || it->second.empty()) {
            return stats;
        }
        
        const auto& samples = it->second;
        stats.sample_count = samples.size();
        
        if (stats.sample_count > 0) {
            // 计算基本统计量
            stats.min_latency = *std::min_element(samples.begin(), samples.end());
            stats.max_latency = *std::max_element(samples.begin(), samples.end());
            stats.avg_latency = std::accumulate(samples.begin(), samples.end(), 0.0) / stats.sample_count;
            
            // 计算分位数
            std::vector<double> sorted_samples(samples.begin(), samples.end());
            std::sort(sorted_samples.begin(), sorted_samples.end());
            
            size_t p95_index = static_cast<size_t>(stats.sample_count * 0.95);
            size_t p99_index = static_cast<size_t>(stats.sample_count * 0.99);
            
            stats.p95_latency = sorted_samples[p95_index];
            stats.p99_latency = sorted_samples[p99_index];
        }
        
        return stats;
    }
    
    // 打印所有阶段的延迟统计信息
    void printStats() const {
        std::cout << "\n系统延迟统计:" << std::endl;
        std::cout << "----------------------------------------" << std::endl;
        std::cout << "阶段\t\t样本数\t最小\t平均\t95分位\t99分位\t最大(微秒)" << std::endl;
        std::cout << "----------------------------------------" << std::endl;
        
        for (const auto& [stage, _] : latency_samples_) {
            auto stats = getLatencyStats(stage);
            std::cout << stage << "\t"
                     << stats.sample_count << "\t"
                     << stats.min_latency << "\t"
                     << stats.avg_latency << "\t"
                     << stats.p95_latency << "\t"
                     << stats.p99_latency << "\t"
                     << stats.max_latency << std::endl;
        }
        std::cout << "----------------------------------------" << std::endl;
    }
    
    // 重置统计信息
    void reset() {
        std::lock_guard<std::mutex> lock(mutex_);
        latency_samples_.clear();
    }

private:
    PerformanceMonitor() = default;
    ~PerformanceMonitor() = default;
    PerformanceMonitor(const PerformanceMonitor&) = delete;
    PerformanceMonitor& operator=(const PerformanceMonitor&) = delete;
    
    mutable std::mutex mutex_;
    std::unordered_map<std::string, std::deque<double>> latency_samples_;
};

// 延迟测量辅助类
class LatencyTimer {
public:
    LatencyTimer(const std::string& stage) : stage_(stage) {
        start_time_ = std::chrono::high_resolution_clock::now();
    }
    
    ~LatencyTimer() {
        auto end_time = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
            end_time - start_time_).count();
        PerformanceMonitor::getInstance()->recordLatency(stage_, duration);
    }

private:
    std::string stage_;
    std::chrono::high_resolution_clock::time_point start_time_;
};

} // namespace hft 